C/C++

推荐列表 站点导航

当前位置:首页 > 脚本编程 > C/C++ >

C++模板:辨别函数类型

来源:网络整理  作者:网友投稿  发布时间:2020-12-27 15:33
在《C 43; 43;Template》中有一个辨识函数类型的模板技术,原文的例子貌 20284;有些错误,这里做个对比验证,如有错误...

在《C++ Template》中有一个辨识函数类型的模板技术,原文的例子貌似有些错误,这里做个对比验证,如有错误,请大家指出,原文的代码如下:

template<typename T> class CompoundT { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef T BottomT; typedef CompoundT<void> ClassT; };
这是基本模板,接着需要定义一个基本模板的特化,用于识别函数类型:

template<typename T> class CompoundT<T()> { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 }; typedef T BaseT(); typedef T BottomT(); typedef CompoundT<void> ClassT; };

这个经过特化的类模板可以识别无参的函数类型,为了灵活使用,原文通过一个模板函数来完成具体的识别工作,如下:template<typename T> void test(T){ cout<<typeid(T).name()<<endl; cout<<(CompoundT<T>::IsFuncT)<<endl; }这个模板函数到底能不能工作呢,我们可以实地验证一下:void fun(){} int main(){ test(fun); return 0; }

发现输出的结果如下:

typeid(T).name() : PFvvE

CompoundT<T>:: IsFuncT : 0

显然,识别的结果是错误的,问题是出在test的定义上,注意到test的参数列表时(T),也就是说采用了传值方式,而如果传递的是函数,会发生decay,即将函数名称decay为函数指针,所以 T 被推断成了函数指针类型,而不是函数类型,所以上面定义的特化版本无法与之匹配。现在将test重新定义如下:(将T改成T&)

template<typename T> void test(T&){ cout<<typeid(T).name()<<endl; cout<<(CompoundT<T>::IsFuncT)<<endl; } 再次执行相同的测试,结果如下:

typeid(T).name() : FvvE

CompoundT<T>:: IsFuncT : 1

可见,这样就可以正确识别函数类型了。此外,我们也可以看到模板函数与模板类结合使用的巨大优势,因为模板函数可以进行类型推断(类型演绎)。如果不使用函数模板,CompoundT的作用就大大下降了,因为不能写成CompoundT<fun>,因为fun不是一个类型,fun相当于类型的实例。为了更加具体地说明这一点,我们可以进行如下定义: typedef void func();这样就可以使用CompoundT<func>了,因为func现在是一个函数类型。

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://v30.fanwenzhu.com/jiaob/cjj/9730.shtml

最新文章
只需要在调用Ctrl+B编译后 只需要在调用Ctrl+B编译后

时间:2021-01-13

OpenGL超级宝典visual studio OpenGL超级宝典visual studio

时间:2021-01-04

Directx11 教程(2) 基本的wi Directx11 教程(2) 基本的wi

时间:2021-01-04

LeetCode11ContainerWithMostWate LeetCode11ContainerWithMostWate

时间:2021-01-04

C语言简单IT之家速成 C语言简单IT之家速成

时间:2020-12-27

三分钟了解Activity工作流 三分钟了解Activity工作流

时间:2020-12-27

编译器是如何实现32位整型 编译器是如何实现32位整型

时间:2020-12-27

C++中lower_bound函数和upper C++中lower_bound函数和upper

时间:2020-12-27

Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

C++模板:辨别函数类型

2020-12-27 编辑:网友投稿

在《C++ Template》中有一个辨识函数类型的模板技术,原文的例子貌似有些错误,这里做个对比验证,如有错误,请大家指出,原文的代码如下:

template<typename T> class CompoundT { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef T BottomT; typedef CompoundT<void> ClassT; };
这是基本模板,接着需要定义一个基本模板的特化,用于识别函数类型:

template<typename T> class CompoundT<T()> { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 }; typedef T BaseT(); typedef T BottomT(); typedef CompoundT<void> ClassT; };

这个经过特化的类模板可以识别无参的函数类型,为了灵活使用,原文通过一个模板函数来完成具体的识别工作,如下:template<typename T> void test(T){ cout<<typeid(T).name()<<endl; cout<<(CompoundT<T>::IsFuncT)<<endl; }这个模板函数到底能不能工作呢,我们可以实地验证一下:void fun(){} int main(){ test(fun); return 0; }

发现输出的结果如下:

typeid(T).name() : PFvvE

CompoundT<T>:: IsFuncT : 0

显然,识别的结果是错误的,问题是出在test的定义上,注意到test的参数列表时(T),也就是说采用了传值方式,而如果传递的是函数,会发生decay,即将函数名称decay为函数指针,所以 T 被推断成了函数指针类型,而不是函数类型,所以上面定义的特化版本无法与之匹配。现在将test重新定义如下:(将T改成T&)

template<typename T> void test(T&){ cout<<typeid(T).name()<<endl; cout<<(CompoundT<T>::IsFuncT)<<endl; } 再次执行相同的测试,结果如下:

typeid(T).name() : FvvE

CompoundT<T>:: IsFuncT : 1

可见,这样就可以正确识别函数类型了。此外,我们也可以看到模板函数与模板类结合使用的巨大优势,因为模板函数可以进行类型推断(类型演绎)。如果不使用函数模板,CompoundT的作用就大大下降了,因为不能写成CompoundT<fun>,因为fun不是一个类型,fun相当于类型的实例。为了更加具体地说明这一点,我们可以进行如下定义: typedef void func();这样就可以使用CompoundT<func>了,因为func现在是一个函数类型。

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://v30.fanwenzhu.com/jiaob/cjj/9730.shtml

相关文章

风云图片

推荐阅读

返回C/C++频道首页